Skip to content

Add Japanese localization of Academy at /academy/japan/#3018

Open
kurosawa-gao wants to merge 2 commits into
langfuse:mainfrom
gao-ai-com:feat/academy-japan
Open

Add Japanese localization of Academy at /academy/japan/#3018
kurosawa-gao wants to merge 2 commits into
langfuse:mainfrom
gao-ai-com:feat/academy-japan

Conversation

@kurosawa-gao
Copy link
Copy Markdown

@kurosawa-gao kurosawa-gao commented May 28, 2026

Motivation

The Langfuse Academy is a strong introduction to AI engineering and
LLMOps fundamentals — content that's especially valuable for teams
new to LLM observability. A Japanese translation makes this learning
path accessible to Japanese developers and lowers the barrier to
applying the practices it covers.

Summary

  • Adds Japanese localization of the Langfuse Academy at /academy/japan/.
  • Covers Tracing, Monitoring (+ Error Analysis), Datasets, Experiments,
    Evaluation, and the AI Engineering Loop overview.
  • Adds a FAQ entry on the existing /japan landing page that links to
    the Japanese Academy.
  • Several Academy TSX components (LoopDiagram, ManualGuideCallout,
    diagram components, etc.) accept an optional locale prop and render
    Japanese strings when locale="ja". Without the prop they render
    unchanged, so existing English pages are unaffected by default.

Context

@kamonspecial reached out offering to contribute a Japanese
translation, and @clemra agreed to the proposed /academy/japan/
path as a starting point. Any future URL adjustments will be on
Langfuse as the broader internationalization approach takes shape.

A small "Translation by GAO, Inc." credit appears at the bottom of
each Japanese page. This wasn't part of the earlier discussion, so
happy to remove or change it if preferred.

One figure (experimentation.png) is left in English; this can be
revisited once Figma source coordination is possible.

Test plan

  • All Japanese pages render correctly (8 pages, HTTP 200, visual
    spot-check on /academy/japan/tracing).
  • Anchor links (e.g., #user-feedback) work as expected.
  • Existing English Academy pages render unchanged after the
    app/academy → app/academy/(en) route group rename (verified
    /academy and /academy/tracing visually).

Thanks for considering — happy to address any feedback.

🤖 Generated with Claude Code

Greptile Summary

This PR adds a full Japanese localization of the Langfuse Academy at /academy/japan/, implemented as a standalone Fumadocs collection rather than the built-in i18n layer, so the new URLs live naturally under /academy/japan/ without a locale prefix.

  • Eight new MDX pages covering Tracing, Monitoring, Error Analysis, Datasets, Experiments, Evaluation, the AI Engineering Loop overview, and an index — all in Japanese. The English academy is moved into an (en) route group (URL-transparent) and its Fumadocs collection now excludes japan/** so there is no overlap.
  • Nine TSX diagram/callout components accept an optional locale prop and render Japanese strings when locale=\"ja\"; existing English pages are unaffected.
  • A bottomSuffix slot is added to DocsChromePage to render the "Translation by GAO, Inc." attribution, and the /japan landing page gains a FAQ entry linking to the new Japanese Academy.

Confidence Score: 4/5

Safe to merge. The English academy is unaffected by the route-group rename, the collection exclusion patterns are correct, and all new locale-aware component props are optional with backwards-compatible defaults.

The change is well-scoped: new content files, a parallel Fumadocs collection, and additive locale props on existing components. The only findings are cosmetic — a missing noreferrer on one external link and a handful of diagram labels left in English for the Japanese locale, which may be intentional for technical-term consistency with the Langfuse UI.

app/academy/japan/[[...slug]]/page.tsx for the attribution link's rel attribute; components/academy/TracingHierarchyDiagram.tsx and components/academy/EvaluationEvolutionDiagram.tsx for the untranslated visible labels.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Request: /academy/japan/[...slug]"] --> B["app/academy/japan/[[...slug]]/page.tsx"]
    C["Request: /academy/[...slug]"] --> D["app/academy/(en)/[[...slug]]/page.tsx"]
    B --> E["academyJaSource.getPage(slug)"]
    D --> F["academySource.getPage(slug)"]
    E --> G["content/academy/japan/**/*.mdx\n(academyJa collection)"]
    F --> H["content/academy/**/*.mdx\n(excludes japan/**)"]
    B --> I["DocsChromePage + bottomSuffix (GAO attribution)"]
    D --> J["DocsChromePage (no suffix)"]
    I --> M["Locale-aware components\ne.g. LoopDiagram locale='ja'"]
Loading
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
app/academy/japan/[[...slug]]/page.tsx:24
The attribution link uses `rel="noopener"` but omits `noreferrer`. Without `noreferrer`, the browser sends a `Referer` header to gao-ai.com on every click, revealing to that server that the visitor came from the Langfuse docs page. `noreferrer` also implies `noopener`, so both concerns are covered by using it alone.

```suggestion
            rel="noopener noreferrer"
```

### Issue 2 of 3
components/academy/TracingHierarchyDiagram.tsx:50-56
**Labels "Session", "Trace", and "Observation" left in English for Japanese locale**

The `locale` prop is accepted and used for the `aria-label`, but the three visible caption strings (`Session`, `Trace`, `Observation`) remain hardcoded in English. Japanese users will see a diagram where the ring labels are in English while the surrounding page text uses "セッション" and "オブザベーション". If these terms are intentionally kept in English (e.g., to match Langfuse's UI labels), a comment explaining that would prevent future confusion.

### Issue 3 of 3
components/academy/EvaluationEvolutionDiagram.tsx:313-335
**`step` captions ("Step 01/02/03") are not translated for the Japanese locale**

The `title` prop of each `Stage` is correctly branched on `locale === "ja"`, but the `step` prop is always the English string `"Step 01"` / `"Step 02"` / `"Step 03"`. The rendered caption is visible to users (`evaluation-evolution__caption` renders it directly). If keeping English is intentional — since numerals and "Step" are widely understood — a brief comment would clarify the design decision.

Reviews (1): Last reviewed commit: "feat(academy): Japanese localization at ..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

- Localize Academy pages: Tracing, Monitoring + Error Analysis, Datasets, Experiments, Evaluation, AI Engineering Loop.
- Add index page and meta.json for the Japanese section.
- Add a FAQ entry on the /japan LP linking to the Japanese Academy.
- Add a "Translation by GAO, Inc." credit (visible link) on each Japanese Academy page.
- TSX components (LoopDiagram, ManualGuideList, etc.) accept a `locale` prop and render Japanese strings when locale="ja".
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 28, 2026

@kurosawa-gao is attempting to deploy a commit to the langfuse Team on Vercel.

A member of the Team first needs to authorize it.

@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label May 28, 2026
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@dosubot dosubot Bot added the documentation Improvements or additions to documentation label May 28, 2026
Comment thread app/academy/japan/[[...slug]]/page.tsx Outdated
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@kurosawa-gao
Copy link
Copy Markdown
Author

Regarding the untranslated labels noted by greptile-apps:

  • EvaluationEvolutionDiagram: Step 01/02/03 are decorative step-number labels. The title text below each step (手動レビュー, 失敗モードを特定する, 自動化) is already locale-aware and renders in Japanese.
  • TracingHierarchyDiagram: Session, Trace, Observation are intentionally kept in English — they match the exact terms displayed in the Langfuse app UI, so Japanese readers can map the diagram directly to the interface they see.

@clemra
Copy link
Copy Markdown
Member

clemra commented May 29, 2026

@claude review

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a large content PR (29 files, XXL) adding Japanese Academy localization — code-side changes look clean and additive (optional locale props on Academy components default to English, the new japan collection is isolated from the existing academy collection, and the route-group rename to app/academy/(en)/ is URL-transparent), but the Japanese translation quality and the user-facing decisions (intentional English labels for "Session/Trace/Observation" and "Step 01/02/03", GAO attribution placement) are worth a human signoff.

Extended reasoning...

Overview

This PR adds a Japanese localization of the Langfuse Academy at /academy/japan/ via:

  • A new Fumadocs collection (academyJa) loaded from content/academy/japan/, separate from the English academy collection (which now excludes japan/**).
  • Route restructure: app/academyapp/academy/(en) (URL-transparent route group) plus a new app/academy/japan/[[...slug]]/ route.
  • 8 new Japanese MDX pages (Tracing, Monitoring + Error Analysis, Datasets, Experiments, Evaluation, AI Engineering Loop, index).
  • Optional locale prop threaded through 9 Academy TSX components (LoopDiagram, LoopSubset, ManualGuideCallout, AgentPromptCallout, and several diagram components) that render Japanese strings when locale="ja" and English otherwise.
  • A new bottomSuffix slot on DocsChromePage for the "Translation by GAO, Inc." attribution.
  • A FAQ entry on the /japan landing page linking to the Japanese Academy.

Security risks

Minimal. The only external link added (gao-ai.com attribution) was flagged by Greptile for missing noreferrer; the PR was opened with rel="noopener noreferrer" already in place. No auth/permissions/crypto code is touched.

Level of scrutiny

Medium. The TS/code surface area is small and additive — locale is optional everywhere and defaults preserve existing English rendering, so the English Academy is unaffected. The route-group rename is a no-op for URLs but worth verifying that breadcrumbs/canonicals still resolve. The bulk of the diff is Japanese content, which deserves a native-speaker / domain review for terminology consistency (especially the intentional English-vs-Japanese label decisions the author called out: Session/Trace/Observation kept in English to match the Langfuse UI; "Step 01/02/03" kept as decorative numerals).

Other factors

  • The author actively engaged with the Greptile review and provided a clear rationale for the intentional untranslated labels.
  • Two minor nits flagged by the bug hunter (inline): a dead locale="ja" prop on ManualGuideList and a STEPS.length vs steps.length inconsistency in ErrorAnalysisProcessDiagram. Both are cosmetic and have no user-visible defect today.
  • The PR is labeled size:XXL (29 files) and adds a third-party attribution (GAO, Inc.) that the author explicitly flagged as not previously discussed — that's a small editorial/branding decision worth a maintainer call.

Comment on lines +197 to +198
<ManualGuideList
locale="ja"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 <ManualGuideList locale="ja" title="その他のガイド" guides={...}/> passes a locale="ja" prop, but ManualGuideList only accepts { title?, guides } — React silently drops the unknown prop. It's currently harmless because title is explicitly overridden, but it's misleading dead code that pattern-matches the other locale-aware Academy components in this PR (LoopDiagram, ManualGuideCallout, EvaluationEvolutionDiagram, etc.). Either drop the locale prop from the call site or extend ManualGuideList to accept it for consistency.

Extended reasoning...

What the bug is

In content/academy/japan/evaluate.mdx (lines 197–222), the call site renders:

<ManualGuideList
  locale="ja"
  title="その他のガイド"
  guides={[ ... ]}
/>

But components/academy/ManualGuideList.tsx defines its props as { title?: string; guides: ManualGuideListItem[] } and its body destructures only { title = "Guides", guides }. React silently ignores unknown props on functional/non-DOM components, so locale="ja" is dead code — it never reaches any rendering logic.

Why it doesn't blow up today

The component currently has nothing locale-dependent that the caller doesn't already control:

  • title is explicitly overridden to "その他のガイド", so the default English "Guides" never appears.
  • Each GuideRow renders caller-provided topic/lede strings verbatim — those are already Japanese in the guides array.

So visually the output is identical with or without locale="ja". Functional impact today: zero.

Why it still matters

This PR threads a locale prop through nine other Academy components (LoopDiagram, ManualGuideCallout, AgentPromptCallout, DatasetFieldsDiagram, ErrorAnalysisProcessDiagram, EvaluationEvolutionDiagram, LoopSubset, RagTraceViewDiagram, TracingHierarchyDiagram) — and in all of those the prop actually does something. A reader scanning this MDX would reasonably assume locale="ja" here also has effect, and a future contributor adding a localizable string to ManualGuideList (e.g. a default "More guides" ribbon) would silently inherit a broken locale wire-up.

Step-by-step proof

  1. Author writes <ManualGuideList locale="ja" title="その他のガイド" guides={...}/> in evaluate.mdx.
  2. MDX compiles this to React.createElement(ManualGuideList, { locale: "ja", title: "その他のガイド", guides: [...] }).
  3. ManualGuideList is defined as function ManualGuideList({ title = "Guides", guides }: ManualGuideListProps) — only title and guides are destructured.
  4. JavaScript destructuring ignores any extra keys on the props object, so locale is never read.
  5. ManualGuideList does not spread ...rest onto a DOM node or pass props through anywhere, so React never warns about an unknown DOM attribute either.
  6. The component renders identically whether locale="ja" is present or absent.

How to fix

Two equally valid options, depending on whether ManualGuideList is expected to grow locale-aware strings later:

  • Drop the prop (smallest change): remove locale="ja" from the MDX call site in evaluate.mdx. title is already explicitly localized.
  • Extend the component (matches the rest of the PR): add locale?: string to ManualGuideListProps, destructure it, and use it for the default ribbon label (e.g. title = locale === "ja" ? "ガイド" : "Guides") — mirroring how ManualGuideCallout localizes its ribbonPrefix and ctaText.

Severity: nit — cleanup/consistency, no current user-visible defect.

style={{ transform: `scale(${estScale})` }}
>
{STEPS.map((step, i) => (
{steps.map((step, i) => (
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 The .map at line 105 iterates the locale-aware steps array, but the connector guard at line 120 still references STEPS.length (the English-only constant). Both STEPS and STEPS_JA happen to have 5 entries today, so there is no user-visible defect, but a future contributor adding or removing a step from one array only would render an orphan connector or miss one. One-line fix: STEPS.lengthsteps.length.

Extended reasoning...

What the bug is. This PR introduces a locale-aware steps array (const steps = locale === "ja" ? STEPS_JA : STEPS) and correctly switches the .map call at line 105 from STEPS.map to steps.map. However, the connector guard immediately below at line 120 still reads {i < STEPS.length - 1 && ...}, referencing the English-only STEPS constant rather than the locale-selected steps array.

Why it's latent today. STEPS and STEPS_JA each contain exactly 5 entries, so STEPS.length === steps.length for every supported locale and the rendered output is identical to using steps.length. No user will see a visual defect on this PR as it stands — this is purely a code-quality / consistency issue.

Why it still matters. The diff introduced steps precisely to abstract over locale, and one of the two sites that needs it was missed. The inconsistency is a footgun for future contributors: if someone adds or removes a step from STEPS_JA (or adds a third locale array, e.g. STEPS_DE) and forgets to make a matching edit to STEPS, the connector count will no longer match the rendered step count — producing either an orphan trailing connector or a missing connector between the last two cards.

Step-by-step proof. Suppose a future contributor adds a 6th step to STEPS_JA:

  1. steps = STEPS_JA now has length 6.
  2. The .map at line 105 renders 6 step cards (indices i=0..5).
  3. The guard at line 120 evaluates i < STEPS.length - 1, i.e. i < 4 (because STEPS.length is still 5).
  4. Connectors are rendered for i=0,1,2,3 — only 4 connectors between 6 cards.
  5. The 5th and 6th cards have no connector between them. Conversely, if a step is removed from STEPS while STEPS_JA keeps 5, an extra connector renders past the last card.

How to fix. Change STEPS.length to steps.length on line 120 so the guard derives from the same array being iterated. This is the same one-line change Greptile-style reviewers would call out — defensive, consistent with the abstraction the diff introduced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants